package com.tiancikeji.zaoke.app.dao.order.impl;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.commons.lang.StringUtils;
import org.springframework.jdbc.core.BatchPreparedStatementSetter;
import org.springframework.jdbc.core.PreparedStatementCreator;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.core.support.JdbcDaoSupport;
import org.springframework.jdbc.support.GeneratedKeyHolder;
import org.springframework.jdbc.support.KeyHolder;

import com.tiancikeji.zaoke.app.dao.order.OrderDao;
import com.tiancikeji.zaoke.app.model.order.Order;
import com.tiancikeji.zaoke.app.model.order.OrderFood;

public class OrderDaoImpl extends JdbcDaoSupport implements OrderDao{
	
	class OrderRowMapper implements RowMapper<Order>{

		public Order mapRow(ResultSet rs, int rowNum) throws SQLException {
			Order order = new Order();
			order.setOrderId(rs.getLong("order_id"));
			order.setUserId(rs.getLong("user_id"));
			order.setUserName(rs.getString("user_name"));
			order.setZoneId(rs.getLong("zone_id"));
			order.setSalePrice(rs.getDouble("sale_price"));
			order.setPayWay(rs.getInt("pay_way"));
			order.setState(rs.getInt("state"));
			//order.setOrderTime(rs.getDate("order_time"));
			order.setOrderTime(new Date(rs.getTimestamp("order_time").getTime()));
			order.setBookTime(rs.getDate("book_time"));
			if(rs.getDate("consume_time") != null)
				order.setConsumeTime((new Date(rs.getDate("consume_time").getTime())));
			return order;
		}
	}

	private static final String TABLE = "`zaoke`.`order`";

	private static final String TABLE_FOOD = "`zaoke`.`order_food`";

	private static final String TABLE_ID = "`zaoke`.`order_id_gen`";
	
	private static final String QUERY_VIEW = "`order_id`, `user_id`, `user_name`, `zone_id`, `sale_price`, `pay_way`, `state`, `order_time`, `book_time`, `consume_time`";
	
	private static final String QUERY_VIEW_FOOD = "`order_id`, `user_id`, `food_id`, `food_name`, `food_type`, `sale_price`";

	public Order getOrderById(long orderid) {
		String sql = "select " + QUERY_VIEW + " from " + TABLE + " where `order_id` = ? ";
		List<Order> orders = getJdbcTemplate().query(sql, new Object[]{orderid}, new OrderRowMapper());
		
		if(orders != null && orders.size() > 0)
			return orders.get(0);
		
		return null;
	}

	public List<Order> getOrderByUserId(long userid){
		String sql = "select " + QUERY_VIEW + " from " + TABLE + " where `user_id` = ?";
		return getJdbcTemplate().query(sql, new Object[]{userid}, new OrderRowMapper());
	}

	public boolean addOrder(Order order) {
		String sql = "insert into " + TABLE + "(`order_id`, `user_id`, `user_name`, `zone_id`, `sale_price`, `pay_way`, `state`, `order_time`, `book_time`) values(?, ?, ?, ?, ?, ?, ?, ?, ?)";
		return getJdbcTemplate().update(sql, new Object[]{order.getOrderId(), order.getUserId(), order.getUserName(), order.getZoneId(), order.getSalePrice(), order.getPayWay(), order.getState(), order.getOrderTime(), order.getBookTime()}) > 0;
	}
	
	public boolean updateOrderState(int state, Order order){
		String sql = "update " + TABLE + " set state = ? where order_id = ? and state = ?";
		return getJdbcTemplate().update(sql, new Object[]{state, order.getOrderId(), order.getState()}) > 0;
	}

	public Map<Long, List<OrderFood>> getOrderFoodByOrderIds(Set<Long> orderids) {
		String sql = "select " + QUERY_VIEW_FOOD + " from " + TABLE_FOOD + " where `order_id` in (";
		sql += StringUtils.join(orderids, ",");
		sql += ")";
		
		final Map<Long, List<OrderFood>> foods = new HashMap<Long, List<OrderFood>>();
		getJdbcTemplate().query(sql, new RowMapper<Integer>(){

			public Integer mapRow(ResultSet rs, int rowNum) throws SQLException {
				OrderFood food = new OrderFood();
				food.setOrderId(rs.getLong("order_id"));
				food.setUserId(rs.getLong("user_id"));
				food.setFoodId(rs.getLong("food_id"));
				food.setFoodName(rs.getString("food_name"));
				food.setFoodType(rs.getInt("food_type"));
				food.setSalePrice(rs.getDouble("sale_price"));
				
				List<OrderFood> tmp = foods.get(food.getOrderId());
				if(tmp == null){
					tmp = new ArrayList<OrderFood>();
					foods.put(food.getOrderId(), tmp);
				}
				tmp.add(food);
				
				return rowNum;
			}
			
		});
		
		return foods;
	}

	public long genTodayId(final String date, final long zoneId) {
		final String sql = "insert into " + TABLE_ID + " (`date`, `zone_id`, `today_id`) select ?, " + zoneId + ", ifnull(max(today_id),0) + 1 from " + TABLE_ID + " where date= ? and zone_id = ?";
		KeyHolder holder = new GeneratedKeyHolder();
		int count = getJdbcTemplate().update(new PreparedStatementCreator() {
			
			public PreparedStatement createPreparedStatement(Connection con)
					throws SQLException {
				PreparedStatement ps = con.prepareStatement(sql);
				ps.setObject(1, date);
				ps.setObject(2, date);
				ps.setObject(3, zoneId);
				return ps;
			}
		}, holder);
		
		if(count > 0 && holder.getKey() != null){
			long key = holder.getKey().longValue();
			String sql1 = "select today_id from " + TABLE_ID + " where gen_id = " + key;
			return getJdbcTemplate().queryForLong(sql1);
		}
		
		return 0;
	}

	public boolean addFoods(final List<OrderFood> foods) {
		String sql = "insert into" + TABLE_FOOD + "(`order_id`, `user_id`, `food_id`, `food_name`, `food_type`, `sale_price`) values(?, ?, ?, ?, ?, ?)";
		
		getJdbcTemplate().batchUpdate(sql, new BatchPreparedStatementSetter() {
			
			public void setValues(PreparedStatement ps, int i) throws SQLException {
				OrderFood food = foods.get(i);
				ps.setObject(1, food.getOrderId());
				ps.setObject(2, food.getUserId());
				ps.setObject(3, food.getFoodId());
				ps.setObject(4, food.getFoodName());
				ps.setObject(5, food.getFoodType());
				ps.setObject(6, food.getSalePrice());
			}
			
			public int getBatchSize() {
				return foods.size();
			}
		});
		return true;
	}
	
	public boolean updateOrderState(int state, long orderId){
		String sql = "update " + TABLE + " set state = ? where order_id = ?";
		return getJdbcTemplate().update(sql, new Object[]{state, orderId}) > 0;
	}

}
